<template>
  <div>
    <!-- 面包屑 -->
    <el-breadcrumb separator="/">
      <el-breadcrumb-item :to="{ path: '/layout' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item><a>文章管理</a></el-breadcrumb-item>
      <el-breadcrumb-item>文章发布</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 卡片组件 -->
    <el-card>
      <!-- 
            表单组件
            model: 表单数据对象	
            label-width: 表示label的宽度
         -->
      <el-form ref="form" :model="form" label-width="80px">
        <!-- label: 表示标题（标签文本） -->
        <el-form-item label="标题：">
          <el-input v-model="form.title"></el-input>
        </el-form-item>
        <!-- 类型 -->
        <el-form-item label="类型：">
          <el-radio-group @change="typeChange" v-model="form.type">
            <el-radio :label="1">文章</el-radio>
            <el-radio :label="2">视频</el-radio>
          </el-radio-group>
        </el-form-item>
        <!-- 内容 -->

        <el-form-item label="内容：">
            <!-- 富文本 
                使用vue-word-editor插件
                使用文档地址：https://blog.csdn.net/yupyuping/article/details/109524903
                使用步骤：
                    1、下载：npm install vue-word-editor --save
             -->
          <VueEditor v-show="form.type==1" ref="vueEditor" :config="config" />
          
          <!-- 
            上次视频按钮
          :file-list="fileList"

          实现视频上传
            1、配置请求地址：action的值
            2、配置请求头（token值）：headers的值
            3、视频上传成功后，保存视频链接
            4、删除视频，清除对应的数据
            5、上传视频数量超出限制，提示用（on-exceed）
           -->
          <el-upload
            v-show="form.type==2"
            :action="baseURL+'/upload'"
            :headers="headers"
            :limit="1"
            :on-success="videoSuccess"
            :on-remove="videoRemove"
            :on-exceed="videoExceed"
            :file-list="videoList"
            >
            <el-button size="small" type="primary">点击上传</el-button>
            <div slot="tip" class="el-upload__tip">只能上传视频文件</div>
          </el-upload>
        </el-form-item>

        <!-- 栏目 -->
        <el-form-item label="栏目：">
          <!-- 
            indeterminate： 表示复选框的不确定状态（选中了一部分选项，但没有全部选中，则表示不确定状态，true表示不确定状态）
            v-model：表示绑定全选框的状态值
            change: 复选框状态改变时触发的事件
           -->
          <el-checkbox
            :indeterminate="isIndeterminate"
            v-model="checkAll"
            @change="handleCheckAllChange"
            >全选</el-checkbox
          >
          <div style="margin: 15px 0"></div>
          <!-- 
            v-model: 表示选中的所有小选框的集合
            change：小选框状态发生变化时触发的事件
           -->
          <el-checkbox-group
            v-model="checkedCategory"
            @change="handleCheckedCitiesChange"
          >
            <el-checkbox v-for="(item,index) in category" 
            :label="item.id" :key="index">
              {{item.name}}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>
        <!-- 封面 -->
        <el-form-item label="封面：">
          <!-- 
            action：上传文件接口地址

           -->
          <el-upload
          :action="baseURL+'/upload'"
          :headers="headers"
          :on-success="coverSuccess"
          :on-remove="coverRemove"
          :on-exceed="coverExceed"
          :file-list="form.cover"
          :limit="3"
           list-type="picture-card">
            <i class="el-icon-plus"></i>
          </el-upload>
        </el-form-item>
        <!-- 发布文章按钮 -->
        <el-button @click="publishFn">发布文章</el-button>
      </el-form>
    </el-card>
  </div>
</template>

<script>
import VueEditor from "vue-word-editor";
import "quill/dist/quill.snow.css";
import { getCategory } from "@/api/common.js"
import axios from "@/utils/request.js"
import { publish, articleDetail,editArticle } from "@/api/article.js"
// 渲染栏目列表
// 1、封装接口函数
// 2、在文章发布页面引入函数，并在created中调用函数获取栏目列表数据并保存
// 3、根据数据进行渲染

export default {
  // 注册富文本组件
  components: {
    VueEditor,
  },
  data() {
    return {
      baseURL: axios.defaults.baseURL,
      headers:{
        Authorization: localStorage.getItem("token-backend-70")
      },
      form: {
        title: "", // 标题
        type: 1, // 类型1文章 2视频
        content: "", // 内容
        cover: [],
        categories: [], // 栏目
      },
      videoList: [], // 视频显示变量
      config: {
        // 上传图片的配置
        uploadImage: {
          url: axios.defaults.baseURL + "/upload", //文章上传到服务器端的处理路径
          name: "file", //后台所需要的参数的名称
          headers: {
            Authorization: localStorage.getItem("token-backend-70")
          }, //设置请求头信息
          // res是结果，insert方法会把内容注入到编辑器中，res.data.url是资源地址
          uploadSuccess(res, insert) {
            // console.log(129,res);
            insert(axios.defaults.baseURL + res.data.data.url); //文件上传之后的回调，接收服务器响应回来的数据，根据服务器的地址进行填充
          },
        },
      },
      isIndeterminate: false,
      checkAll: false,
      checkedCategory: [], // 小选框选中的栏目集合
      category: [],         // 所有栏目的集合
    };
  },
  created(){
    // 获取栏目列表数据
    getCategory().then(res=>{
      // console.log(115,res);
      // 关注：是用户关注了作者之后才有的，因此不需要参与发表文章时选择
      // 头条：默认所有文章都属性头条，因此不需要参与发表文章时选择
      // 所以，渲染列表的时候直接把“关注”和“头条”删除即可
      this.category = res.data.data.slice(2);
      // console.log(this.category);
    })

    // 获取文章详情
    let id = this.$route.query.id;
    // 编辑文章的时候才需要获取文章详情数据
    if(id){
      articleDetail(id).then(res=>{
        console.log(182,res);
        // 标题回显
        this.form.title = res.data.data.title;
        // 类型回显
        this.form.type = res.data.data.type;
        // 内容回显
        if(this.form.type == 1){
          // 回显富文本的内容
          var quill = this.$refs.vueEditor.editor; 
          quill.clipboard.dangerouslyPasteHTML(0,res.data.data.content);
        }else{
          // 回显视频内容
          this.videoList = [{
            name: "小视频",
            url: res.data.data.content
          }]
          this.form.content = res.data.data.content;
        }
        // 栏目回显
        this.checkedCategory = res.data.data.categories.map(item=>item.id);
        // 封面回显
        // 我们可以给upload组件添加file-list属性进行回显
        this.form.cover = res.data.data.cover.map(item=>{
          // 因为老数据默认有基础地址，新数据没有，所以需要做如下判断
          let url = item.url.indexOf("http")==-1?this.baseURL+ item.url:item.url;
          return {
            name: "封面",
            url: url,
            id: item.id
          }
        })

      })
    }

  },
  methods: {
    // 类型改变的时候，清空内容
    typeChange(){
      // console.log(224);
      this.form.content = "";
      this.videoList = [];
    },
    // 当用户上传的视频数量超出限制的时候，触发的函数
    videoExceed(){
      this.$message({
        message: "只能上传一个视频！",
        type: "warning"
      })
    }, 
    // 移除视频，把content也清空
    videoRemove(){
      this.form.content = "";
    },
    // 视频上传成功,保存视频链接
    videoSuccess(response){
      // console.log(response);
      if(response.message == "文件上传成功"){
        this.form.content = response.data.url;
      }
    },
    // 上传的封面超出规定数量时触发
    coverExceed(){
      // elementUI的提示框
      this.$message({
        message: "封面数量最多上传3张！",
        type: "warning"
      })
    },
    // 移除封面时触发的函数
    coverRemove(file, fileList){
      // file: 被删除的图片文件对象
      // fileList：剩下下未删除的图片集合
      // console.log(147,fileList);
      this.form.cover = fileList.map(item=>{
        return {
          id: item.id,
          url: item.url
        }
      })
    }, 
    // 封面上传成功后的回调函数
    coverSuccess(response, file, fileList){
      console.log(146,response, file, fileList);
      // 需要把id包装成对象然后再push到数组中，这是后端规定的格式
      this.form.cover.push({
        id: response.data.id,
        url: this.baseURL + response.data.url
      })
    },
    // 点击全选框触发的函数
    handleCheckAllChange(bool){
        // 根据全选框的状态值，把checkedCategory赋值为全部栏目id的集合此刻表示全部选中了，
        // checkedCategory赋值为空数组，则表示取消全选
        this.checkedCategory = bool?this.category.map(item=>item.id):[];
        // 不管全部选中还是全部不选中，都是确定状态，因此直接把isIndeterminate设置成false即可
        this.isIndeterminate = false;
    },
    // 点击小选框触发的函数
    handleCheckedCitiesChange(val){
      // val：表示选中的选项集合
        // 设置全选框的不确定的状态，isIndeterminate值为true表示不确定状态
        // 当选中的选项不为空，且选中的选中长度不等于全部栏目数组长度的时候表示“不确定状态”
        this.isIndeterminate = val.length!=this.category.length&&val.length?true:false;
        // 当小选框全部选中的时候，自动把全选框也选中
        // 当选中的选项集合的长度等于所有栏目集合长度的时候表示已经全部选中了
        this.checkAll = val.length==this.category.length?true:false;
    },
    // 发布文章
    publishFn() {
      // 获取富文本内容
      // 当类型为1的时候，内容才是富文本的内容
      // 类型为2的时候，内容是视频连接
      if(this.form.type == 1){
        var content = this.$refs.vueEditor.editor.root.innerHTML;
        this.form.content = content;
      }
      // 判断内容不能为空
      // 判断标题
      if(!this.form.title){
        this.$message.warning("标题不能为空！")
        return
      }
      // 判断内容是否为空
      if(this.form.type == 1){
        // 判断富文本内容是否为空
        // 当富文本内容为空的时候，默认会返回一个换行符，因此不能简单的判断内容是否为空。
        // 那如何判断内容为空呢？答：富文本提供了一个方法getLength进行判断，当getLength方法返回1的时候
        // 说明，富文本内容为空，否则不为空。
        // console.log(259,this.form.content);
        var quill = this.$refs.vueEditor.editor;
        let length = quill.getLength();
        if(length == 1){
          this.$message.warning("富文本内容不能为空！")
          return
        }
      }else{
        // 判断视频是否为空
        if(!this.form.content){
          this.$message.warning("视频不能为空！")
          return
        }
      }
      // 栏目判断
      if(this.checkedCategory.length == 0){
        this.$message.warning("栏目不能为空！")
        return
      }
      // 封面判断
      if(this.form.cover.length == 0){
        this.$message.warning("封面不能为空！")
        return
      }

      // 选中的栏目id集合
      this.form.categories = this.checkedCategory.map(id=>{
        return {
          id: id
        }
      })

      // 编辑文章
      // 判断 用户是否在编辑
      let id = this.$route.query.id;
      if(id){
        // id存在调用编辑文章接口
        editArticle(id,this.form).then(res=>{
          console.log(340,res);
          if(res.data.message == "文章编辑成功"){
            this.$router.push("/layout/articleList");
            this.$message.success(res.data.message);
            return
          }
          this.$message.error(res.data.message);
        })
        return
      }
      // 新增文章
      publish(this.form).then(res=>{
        console.log(209,res);
        if(res.data.message == "文章发布成功"){
          this.$router.push("/layout/articleList");
          this.$message.success(res.data.message);
          return
        }
        this.$message.error(res.data.message);
      })
      // console.log(79, content);
      // console.log(198,this.form);
    },
  },
};
</script>

<style lang="less" scoped>
.el-card {
  margin-top: 20px;
}
</style>